﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;

namespace MobileSignatureCapture
{
    public partial class frmMain : Form
    {
        private int x1 = -1;
        private int y1 = -1;
        private int x2 = -1;
        private int y2 = -1;

        private Color signatureColor = Color.Black;
        private Pen pen = new Pen(Color.Black);

        private int width = 1;

        public frmMain()
        {
            InitializeComponent();
        }

        private void pictureBox_MouseMove(object sender, MouseEventArgs e)
        {
            if (pen.Color != signatureColor)
                pen = new Pen(signatureColor);

            if (pen.Width != width)
                pen.Width = width;

            x1 = x2;
            y1 = y2;
            x2 = e.X;
            y2 = e.Y;

            if (x1 == -1 && y1 == -1)
                return;

            pictureBoxSignature.CreateGraphics().DrawLine(pen, x1, y1, x2, y2);
        }

        private void pictureBoxBlack_Click(object sender, EventArgs e)
        {
            signatureColor = Color.Black;
        }

        private void pictureBoxRed_Click(object sender, EventArgs e)
        {
            signatureColor = Color.Red;
        }

        private void pictureBoxGreen_Click(object sender, EventArgs e)
        {
            signatureColor = Color.Green;
        }

        private void pictureBoxBlue_Click(object sender, EventArgs e)
        {
            signatureColor = Color.Blue;
        }

        private void pictureBoxYellow_Click(object sender, EventArgs e)
        {
            signatureColor = Color.Yellow;
        }

        private void pictureBoxWhite_Click(object sender, EventArgs e)
        {
            signatureColor = Color.White;
        }

        private void pictureBoxSignature_MouseUp(object sender, MouseEventArgs e)
        {
            Reset();
        }

        private void Reset()
        {
            x1 = -1;
            y1 = -1;
            x2 = -1;
            y2 = -1;
        }

        private void menuItem1Pixel_Click(object sender, EventArgs e)
        {
            width = 1;
        }

        private void menuItem3Pixels_Click(object sender, EventArgs e)
        {
            width = 3;
        }

        private void menuItem5Pixels_Click(object sender, EventArgs e)
        {
            width = 5;
        }

        private void menuItemClear_Click(object sender, EventArgs e)
        {
            pictureBoxSignature.CreateGraphics().Clear(Color.White);
        }

        private void menuItemExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void menuItemAbout_Click(object sender, EventArgs e)
        {
            frmAbout aboutForm = new frmAbout();
            aboutForm.ShowDialog();
        }

        private void timer_Tick(object sender, EventArgs e)
        {
            panelBlack.Tag = true;
            panelRed.Tag = true;
            panelGreen.Tag = true;
            panelBlue.Tag = true;
            panelYellow.Tag = true;
            panelWhite.Tag = true;

            switch (GetColorName(signatureColor))
            {
                case "Black":
                    panelBlack.Tag = !panelBlack.Visible;
                    break;
                case "Red":
                    panelRed.Tag = !panelRed.Visible;
                    break;
                case "Green":
                    panelGreen.Tag = !panelGreen.Visible;
                    break;
                case "Blue":
                    panelBlue.Tag = !panelBlue.Visible;
                    break;
                case "Yellow":
                    panelYellow.Tag = !panelYellow.Visible;
                    break;
                case "White":
                    panelWhite.Tag = !panelWhite.Visible;
                    break;
            }

            panelBlack.Visible = (bool)panelBlack.Tag;
            panelRed.Visible = (bool)panelRed.Tag;
            panelGreen.Visible = (bool)panelGreen.Tag;
            panelBlue.Visible = (bool)panelBlue.Tag;
            panelYellow.Visible = (bool)panelYellow.Tag;
            panelWhite.Visible = (bool)panelWhite.Tag;
        }

        private static string GetName(Type enumType, object value)
        {
            return Enum.ToObject(enumType, value).ToString();
        }

        private static string GetColorName(Color inputColor)
        {
            string colorName = string.Empty;

            Type colorType = inputColor.GetType();
            if (null != colorType)
            {
                PropertyInfo[] propInfoList =
                 colorType.GetProperties(BindingFlags.Static | BindingFlags.DeclaredOnly
                    | BindingFlags.Public);
                for (int i = 0; i < propInfoList.Length; i++)
                {
                    PropertyInfo propInfo = (PropertyInfo)propInfoList[i];
                    Color color = (Color)propInfo.GetValue(null, null);

                    if (color == inputColor)
                        colorName = propInfo.Name;
                }
            }

            return colorName;
        }

        private void menuItemSave_Click(object sender, EventArgs e)
        {
            Save("signature.bmp", pictureBoxSignature.CreateGraphics(), pictureBoxSignature.Bounds);
        }

        // P/Invoke declaration
        [DllImport("coredll.dll")]
        public static extern int BitBlt(IntPtr hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);

        const int SRCCOPY = 0x00CC0020;

        private void Save(string filename, Graphics gx, Rectangle rect)
        {
            Bitmap bmp = new Bitmap(rect.Width, rect.Height);
            // Create compatible graphics
            Graphics gxComp = Graphics.FromImage(bmp);
            // Blit the image data
            BitBlt(gxComp.GetHdc(), 0, 0, rect.Width, rect.Height, gx.GetHdc(), rect.Left, rect.Top, SRCCOPY);
            bmp.Save(filename, System.Drawing.Imaging.ImageFormat.Bmp);
            // Cleanup
            bmp.Dispose();
            gxComp.Dispose();
        }
    }
}